home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Add-Ons / MPW / MPW re2c 1.1 / scanner.re < prev    next >
Encoding:
Text File  |  1995-09-08  |  3.4 KB  |  179 lines  |  [TEXT/MPS ]

  1. // $Log: scanner.re,v $
  2. //Revision 1.1  1994/04/08  15:27:59  peter
  3. //Initial revision
  4. //
  5.  
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <iostream.h>
  9. #include <unistd.h>
  10. #include "scanner.h"
  11. #include "parser.h"
  12. #include "y.tab.h"
  13.  
  14. extern YYSTYPE yylval;
  15.  
  16. #define    BSIZE    8192
  17.  
  18. #define    YYCTYPE        uchar
  19. #define    YYCURSOR    cursor
  20. #define    YYLIMIT        lim
  21. #define    YYMARKER    ptr
  22. #define    YYFILL(n)    {cursor = fill(cursor);}
  23.  
  24. #define    RETURN(i)    {cur = cursor; return i;}
  25.  
  26.  
  27. Scanner::Scanner(int i) : in(i),
  28.     bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL),
  29.     top(NULL), eof(NULL), tchar(0), tline(0), cline(1) {
  30.     ;
  31. }
  32.  
  33. uchar *Scanner::fill(uchar *cursor){
  34.     if(!eof){
  35.     uint cnt = tok - bot;
  36.     if(cnt){
  37.         memcpy(bot, tok, lim - tok);
  38.         tok = bot;
  39.         ptr -= cnt;
  40.         cursor -= cnt;
  41.         pos -= cnt;
  42.         lim -= cnt;
  43.     }
  44.     if((top - lim) < BSIZE){
  45.         uchar *buf = new uchar[(lim - bot) + BSIZE];
  46.         memcpy(buf, tok, lim - tok);
  47.         tok = buf;
  48.         ptr = &buf[ptr - bot];
  49.         cursor = &buf[cursor - bot];
  50.         pos = &buf[pos - bot];
  51.         lim = &buf[lim - bot];
  52.         top = &lim[BSIZE];
  53.         delete bot;
  54.         bot = buf;
  55.     }
  56.     if((cnt = read(in, (char*) lim, BSIZE)) != BSIZE){
  57.         eof = &lim[cnt]; *eof++ = '\n';
  58.     }
  59.     lim += cnt;
  60.     }
  61.     return cursor;
  62. }
  63.  
  64. /*!re2c
  65. any        = [\000-\377];
  66. dot        = any \ [\n];
  67. esc        = dot \ [\\];
  68. cstring        = "["  ((esc \ [\]]) | "\\" dot)* "]" ;
  69. dstring        = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
  70. sstring        = "'"  ((esc \ ['] ) | "\\" dot)* "'" ;
  71. letter        = [a-zA-Z];
  72. digit        = [0-9];
  73. */
  74.  
  75. int Scanner::echo(ostream &out){
  76.     uchar *cursor = cur;
  77.     tok = cursor;
  78. echo:
  79. /*!re2c
  80.     "/*!re2c"        { out.write(tok, &cursor[-7] - tok);
  81.                   tok = cursor;
  82.                   RETURN(1); }
  83.     "\n"            { if(cursor == eof) RETURN(0);
  84.                   out.write(tok, cursor - tok);
  85.                   tok = pos = cursor; cline++;
  86.                   goto echo; }
  87.         any            { goto echo; }
  88. */
  89. }
  90.  
  91.  
  92. int Scanner::scan(){
  93.     uchar *cursor = cur;
  94.     uint depth;
  95.  
  96. scan:
  97.     tchar = cursor - pos;
  98.     tline = cline;
  99.     tok = cursor;
  100. /*!re2c
  101.     "{"            { depth = 1;
  102.                   goto code;
  103.                 }
  104.     "/*"            { depth = 1;
  105.                   goto comment; }
  106.  
  107.     "*/"            { tok = cursor;
  108.                   RETURN(0); }
  109.  
  110.     dstring            { cur = cursor;
  111.                   yylval.regexp = strToRE(token());
  112.                   return STRING; }
  113.     "\""            { fatal("bad string"); }
  114.  
  115.     cstring            { cur = cursor;
  116.                   yylval.regexp = ranToRE(token());
  117.                   return RANGE; }
  118.     "["            { fatal("bad character constant"); }
  119.  
  120.     [()|=;/\\]        { RETURN(*tok); }
  121.  
  122.     [*+?]            { yylval.op = *tok;
  123.                   RETURN(CLOSE); }
  124.  
  125.     letter (letter|digit)*    { cur = cursor;
  126.                   yylval.symbol = Symbol::find(token());
  127.                   return ID; }
  128.  
  129.     [ \t]+            { goto scan; }
  130.  
  131.     "\n"            { if(cursor == eof) RETURN(0);
  132.                   pos = cursor; cline++;
  133.                   goto scan;
  134.                     }
  135.  
  136.     any            { cerr << "unexpected character: " << *tok << endl;
  137.                   goto scan;
  138.                 }
  139. */
  140.  
  141. code:
  142. /*!re2c
  143.     "}"            { if(--depth == 0){
  144.                     cur = cursor;
  145.                     yylval.token = new Token(token(), tline);
  146.                     return CODE;
  147.                   }
  148.                   goto code; }
  149.     "{"            { ++depth;
  150.                   goto code; }
  151.     "\n"            { if(cursor == eof) fatal("missing '}'");
  152.                   pos = cursor; cline++;
  153.                   goto code;
  154.                 }
  155.     dstring | sstring | any    { goto code; }
  156. */
  157.  
  158. comment:
  159. /*!re2c
  160.     "*/"            { if(--depth == 0)
  161.                     goto scan;
  162.                     else
  163.                     goto comment; }
  164.     "/*"            { ++depth;
  165.                   goto comment; }
  166.     "\n"            { if(cursor == eof) RETURN(0);
  167.                   tok = pos = cursor; cline++;
  168.                   goto comment;
  169.                 }
  170.         any            { goto comment; }
  171. */
  172. }
  173.  
  174. void Scanner::fatal(char *msg){
  175.     cerr << "line " << tline << ", column " << (tchar + 1) << ": "
  176.     << msg << endl;
  177.     exit(1);
  178. }
  179.